<?php
namespace app\app\controller\v1;
use think\Db;
use app\app\util\OnlineUtils;
class OrderController extends  BaseController{

    /**
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 创建机票订单
     */
    public function CreatePlaneOrder()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $id = input('post.id');
        $dateinfo = input('post.dateinfo');
        $price = input('post.price');
        //处理时间
        $year = date('Y',time());
        $time = $year.'/'.$dateinfo;
        $date = strtotime($time);
        //填写个人信息
        $name = input('post.name');
        $phone = input('post.phone');
        $idcard = input('post.idcard');
//        //线路详情
//        $plane = Db::name('plane')->find($id);
//        //判断价格
//        if( $line['ware_type_id'] == 1 ){
//            $fee = $line['price'];
//        }elseif ( $line['ware_type_id'] == 2){
//            $fee = $line['seckill_price'];
//        }
        //生成订单记录
        $order_form_code = date('YmdHis',time());
        $order_code = date('Ymd',time()).rand(100,999);
        $arr = array(
            'order_form_code'=>$order_form_code,
            'order_code'=>$order_code,
            'user_id'=>$user_id,
            'plane_id'=>$id,
            'plane_date'=>$date,
            'plane_price'=>$price,
            'order_num'=>1,
            'create_time'=>time(),
            'name'=>$name,
            'phone'=>$phone,
            'idcard'=>$idcard
        );
        if( Db::name('order')->insertGetId($arr)){
            return json_code(200,'success',$arr);
        }else{
            return json_code(402,'fail');
        }
    }
    /**
     * @return array
     * 创建订单
     */
    public function CreateOrder()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $line_id = input('post.line_id');
        //填写个人信息
        $name = input('post.name');
        $phone = input('post.phone');
        $idcard = input('post.idcard');
        //线路详情
        $line = Db::name('line')->find($line_id);
        //判断价格
        if( $line['ware_type_id'] == 1 ){
            $fee = $line['price'];
        }elseif ( $line['ware_type_id'] == 2){
            $fee = $line['seckill_price'];
        }
        //生成订单记录
        $order_form_code = date('YmdHis',time());
        $order_code = date('Ymd',time()).rand(100,999);
        $arr = array(
            'order_form_code'=>$order_form_code,
            'order_code'=>$order_code,
            'user_id'=>$user_id,
            'ware_id'=>$line_id,
            'order_num'=>1,
            'ware_price'=>$fee,
            'create_time'=>time(),
            'name'=>$name,
            'phone'=>$phone,
            'idcard'=>$idcard
        );
        if( Db::name('order')->insertGetId($arr)){
            return json_code(200,'success',$arr);
        }else{
            return json_code(402,'fail');
        }
    }
    /**
     * @return array
     * 支付
     */
    public function OrderNow()
    {
        $user_id = OnlineUtils::getUserIdBySid();

        $fee = input('post.ware_price');
        $order_form_code = input('post.order_form_code');
        //用户详情
        $user = Db::name('user')->find($user_id);

        $total_fee= intval($fee*100);

        $data = array(
            'appid'  => config('APPID'),
            'mch_id' => config('MCH_ID'),
            'openid' => $user['open_id'],
            'body'   => "长滩岛订单支付",
            'out_trade_no' => $order_form_code,
            'total_fee'    => $total_fee,
            'spbill_create_ip' => $_SERVER["REMOTE_ADDR"],
            'trade_type' => 'JSAPI'
        );
        $post_data = $this->setSendData($data);
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $xml_data = $this->senXml($url,$post_data);
        // return json_code(200,'succcess',$xml_data);
        // 解析返回数据
        $postObj = $this->xmlToObject($xml_data);

        if ($postObj === false) {
            return json_code(402,'false');
            // 如果解析的结果为false，终止程序
            exit;
        }
        if ($postObj->return_code == 'FAIL') {
            return json_code(402,'fail',$postObj->return_msg);            // 如果微信返回错误码为FAIL，则代表请求失败，返回失败信息；
        } else {
            // 如果上一次请求成功，那么我们将返回的数据重新拼装，进行第二次签名
            $resignData = array(
                'appId'       =>    $postObj->appid,
                'signType'    =>    "MD5",
                'nonceStr'    =>    $postObj->nonce_str,
                'timeStamp'   =>    "".time()."",
                'package'     =>    "prepay_id=".$postObj->prepay_id,
            );
            // 二次签名；
            $sign = $this->getSign($resignData);
            $resignData['paySign'] = $sign;
            $resignData['fee'] = $fee;
            return json_code(200,'success',$resignData);
        }
    }

    
//    /**
//     * @return array
//     * 立即购买（下单）
//     */
//    public function OrderNow()
//    {
//        $user_id = OnlineUtils::getUserIdBySid();
////        $user_id  = 1;
//        $line_id = input('post.line_id');
//        //填写个人信息
//        $name = input('post.name');
//        $phone = input('post.phone');
//        $idcard = input('post.idcard');
//        //线路详情
//        $line = Db::name('line')->find($line_id);
//        //用户详情
//        $user = Db::name('user')->find($user_id);
//        //判断价格
//        if( $line['ware_type_id'] == 1 ){
//            $fee = $line['price'];
//        }elseif ( $line['ware_type_id'] == 2){
//            $fee = $line['seckill_price'];
//        }
//        $total_fee= intval($fee*100);
//        //生成订单记录
//        $order_form_code = date('YmdHis',time());
//        $order_code = date('Ymd',time()).rand(100,999);
//        $arr = array(
//			'order_form_code'=>$order_form_code,
//			'order_code'=>$order_code,
//			'user_id'=>$user_id,
//            'ware_id'=>$line_id,
//			'order_num'=>1,
//			'ware_price'=>$fee,
//			'create_time'=>time(),
//			'name'=>$name,
//            'phone'=>$phone,
//			'idcard'=>$idcard
//			);
//        Db::name('order')->insertGetId($arr);
//		$data = array(
//			'appid'  => config('APPID'),
//            'mch_id' => config('MCH_ID'),
//            'openid' => $user['open_id'],
//            'body'   => "长滩岛订单支付",
//            'out_trade_no' => $order_form_code,
//            'total_fee'    => $total_fee,
//            'spbill_create_ip' => $_SERVER["REMOTE_ADDR"],
//            'trade_type' => 'JSAPI'
//		);
//        $post_data = $this->setSendData($data);
//        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//        $xml_data = $this->senXml($url,$post_data);
//		// return json_code(200,'succcess',$xml_data);
//        // 解析返回数据
//        $postObj = $this->xmlToObject($xml_data);
//
//        if ($postObj === false) {
//            return json_code(402,'false');
//            // 如果解析的结果为false，终止程序
//            exit;
//        }
//        if ($postObj->return_code == 'FAIL') {
//            return json_code(402,'fail',$postObj->return_msg);            // 如果微信返回错误码为FAIL，则代表请求失败，返回失败信息；
//        } else {
//            // 如果上一次请求成功，那么我们将返回的数据重新拼装，进行第二次签名
//            $resignData = array(
//                'appId'       =>    $postObj->appid,
//                'signType'    =>    "MD5",
//                'nonceStr'    =>    $postObj->nonce_str,
//                'timeStamp'   =>    "".time()."",
//				'total_fee'   =>     $total_fee,
//                'package'     =>    "prepay_id=".$postObj->prepay_id,
//            );
//            // 二次签名；
//            $sign = $this->getSign($resignData);
//            $resignData['paySign'] = $sign;
//            return json_code(200,'success',$resignData);
//        }
//    }

    /**
     * @return array
     * 从购物车提交订单（下单）
     */
//    public function PlaceOrder()
//    {
//        $user_id = OnlineUtils::getUserIdBySid();
//        $data = input('post.data');
//        //填写个人信息
//        $name = input('post.name');
//        $phone = input('post.phone');
//        $idcard = input('post.idcard');
//        //总价默认0
//        $fee = 0;
//        //用户信息
//        $user = Db::name('user')->find($user_id);
//        $order_form_code = date('YmdHis',time());
//        //提交订单，生成订单记录，将购物车里的数据删除
//        foreach ( $data as $a => $v){
//            $line_id = $v->line_id;
//            $num = $v->num;
//            $price = Db::name('line')->field('price')->find($line_id);
//            $price = $price['price']*$num;
//            $order_code = date('Ymd',time()).rand(100,999);
//            //添加数据
//            $arr = array('order_code'=>$order_code,'user_id'=>$user_id,'ware_id'=>$v->line_id,'order_num'=>$v->num,
//                'ware_price'=>$price,'name'=>$name,'phone'=>$phone,'idcard'=>$idcard,'create_time'=>time(),'order_form_code'=>$order_form_code);
//            $arrs[] = $arr;
//            //订单表生成记录
//            Db::name('order')->insertGetId($arr);
//            //购物车表删除用户带过来的商品记录
//            Db::name('shopping_cart')->where(['user_id'=>$user_id,'line_id'=>$v->line_id])->delete();
//            //共需要付款
//            $fee = $fee + $price;
//        }
//        $total_fee= intval($fee*100);
//        $data = array(
//            'appid' =>config('APPID'),
//            'mch_id'=>config('MCH_ID'),
//            'openid'=>$user['open_id'],
//            'body'  => '长滩岛订单支付',
//            'out_trade_no'=>$order_form_code,
//            'total_fee'   =>intval($total_fee),
//            'spbill_create_ip'=>$_SERVER["REMOTE_ADDR"],
//            'trade_type'=>'JSAPI'
//        );
//        $post_data = $this->setSendData($data);
//
//        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
//        $xml_data = $this->senXml($url,$post_data);
//        //解析返回数据
//        $postObj = $this->xmlToObject($xml_data);
//        if ($postObj === false) {
//            return json_code(402,'false');
//            // 如果解析的结果为false，终止程序
//            exit;
//        }
//        if ($postObj->return_code == 'FAIL') {
//            return json_code(402,'fail',$postObj->return_msg);            // 如果微信返回错误码为FAIL，则代表请求失败，返回失败信息；
//        } else {
//            //如果上一次请求成功，那么我们将返回的数据重新拼装，进行第二次签名
//            $resignData = array(
//                'appId'       =>    $postObj->appid,
//                'signType'    =>    "MD5",
//                'nonceStr'    =>    $postObj->nonce_str,
//                'timeStamp'   =>    "".time()."",
//                'total_fee'   =>     $total_fee,
//                'package'     =>    "prepay_id=".$postObj->prepay_id,
//            );
//            //二次签名；
//            $sign = $this->getSign($resignData);
//            $resignData['paySign'] = $sign;
//            return json_code(200,'success',$resignData);
//        }
//    }


    /**
     * @return array
     *  发送post请求(xml数据)
     */
    private function senXml($url,$xmlData)
    {
        $header[] = "Content-type: text/xml"; //定义content-type为xml,注意是数组
        //初始化
        $ch = curl_init ($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch, CURLOPT_HTTPHEADER,$header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch,CURLOPT_POSTFIELDS, $xmlData);
        //请求结果
        $response = curl_exec($ch);
        //返回错误
        if(curl_errno($ch)){
            print(curl_error($ch));
        }
        curl_close($ch);
        return $response;
    }

    /**
     * @return bool
     * 回调地址
     */
    public function notifyUrl()
    {
        $postXml = $GLOBALS["HTTP_RAW_POST_DATA"];    // 接受通知参数；
        if (empty($postXml)) {
            return false;
        }
        $postObj = $this->xmlToObject($postXml);      // 调用解析方法，将xml数据解析成对象
        if ($postObj === false) {
            return false;
        }
        if (!empty($postObj->return_code)) {
            if ($postObj->return_code == 'FAIL') {
                return false;
            }
        }
        $obj = $postObj;
        if($obj){
            // 拼装数据进行第三次签名
            $data = array(
                'appid'             =>    $obj->appid,
                'bank_type'         =>    $obj->bank_type,
                'cash_fee'          =>    $obj->cash_fee,
                'fee_type'          =>    $obj->fee_type,
                'is_subscribe'      =>    $obj->is_subscribe,
                'mch_id'            =>    $obj->mch_id,
                'nonce_str'         =>    $obj->nonce_str,
                'openid'            =>    $obj->openid,
                'out_trade_no'      =>    $obj->out_trade_no,
                'result_code'       =>    $obj->result_code,
                'return_code'       =>    $obj->return_code,
                'time_end'          =>    $obj->time_end,
                'total_fee'         =>    $obj->total_fee,
                'trade_type'        =>    $obj->trade_type,
                'transaction_id'    =>    $obj->transaction_id
            );
            // 获取签名
            $sign = $this->getSign($data);
            $order_number = $obj->out_trade_no;
            $user = Db::name('user')->where(['open_id'=>$data['openid']])->find();
            /** 将签名得到的sign值和微信传过来的sign值进行比对，如果一致，则证明数据是微信返回的。 */
            if ($sign == $obj->sign) {
                //查询订单
                $order = Db::name('order')->where('order_form_code','eq',$order_number)->find();
                //更改订单状态，添加订单付款时间
                if( $order ){
//                    foreach ( $order as $a => $v){
                        $arr = array('order_status'=>2,'update_time'=>time());
                        Db::name('order')->where('order_id','eq',$order['order_id'])->update($arr);
//                        $arrs[] =$arr;
//                    }
                    (new DistributionController())->compantPayment($user['id'],$order_number);
                    $reply = "<xml>
	                            <return_code><![CDATA[SUCCESS]]></return_code>
	                            <return_msg><![CDATA[订单完成]]></return_msg>
	                         </xml>";
                    echo $reply;      // 向微信后台返回结果。
                    exit;
                }
            }else{
                $reply = "<xml>
                            <return_code><![CDATA[FAIL]]></return_code>
                            <return_msg><![CDATA[验证失败]]></return_msg>
                         </xml>";
                echo $reply;      // 向微信后台返回结果。
                exit;
            }
        }
    }


    /**
     * 生成随机数并返回
     */
    private function getNonceStr() {
        $code = "";
        for ($i=0; $i > 10; $i++) {
            $code .= mt_rand(1000);        //获取随机数
        }
        $nonceStrTemp = md5($code);
        $nonce_str = mb_substr($nonceStrTemp, 5,37);      //MD5加密后截取32位字符
        return $nonce_str;
    }

    /**
     * 获取参数签名；
     * @param  Array  要传递的参数数组
     * @return String 通过计算得到的签名；
     */
    private function getSign($params) {
        ksort($params);        //将参数数组按照参数名ASCII码从小到大排序
        foreach ($params as $key => $item) {
            if (!empty($item)) {         //剔除参数值为空的参数
                $newArr[] = $key.'='.$item;     // 整合新的参数数组
            }
        }
        $stringA = implode("&", $newArr);         //使用 & 符号连接参数
        $stringSignTemp = $stringA."&key=".config('WX_APP_KEY');        //拼接key
        // key是在商户平台API安全里自己设置的
        $stringSignTemp = MD5($stringSignTemp);       //将字符串进行MD5加密
        $sign = strtoupper($stringSignTemp);      //将所有字符转换为大写
        return $sign;
    }

    /**
     * 拼装请求的数据
     * @return  String 拼装完成的数据
     */
    private function setSendData($data) {
        $sTpl = "<xml>
                    <appid><![CDATA[%s]]></appid>
                    <body><![CDATA[%s]]></body>
                    <mch_id><![CDATA[%s]]></mch_id>
                    <nonce_str><![CDATA[%s]]></nonce_str>
                    <notify_url><![CDATA[%s]]></notify_url>
                    <openid><![CDATA[%s]]></openid>
                    <out_trade_no><![CDATA[%s]]></out_trade_no>
                    <spbill_create_ip><![CDATA[%s]]></spbill_create_ip>
                    <total_fee><![CDATA[%d]]></total_fee>
                    <trade_type><![CDATA[%s]]></trade_type>
                    <sign><![CDATA[%s]]></sign>
                </xml>";                          //xml数据模板

        //随机数
        $nonce_str = $this->getNonceStr();
        //异步通知地址
        $notify_url = config('WX_NOTIFY_URL');
        //将要发送的信息数组
        $data['nonce_str'] = $nonce_str;
        $data['notify_url'] = $notify_url;//将参与签名的数据保存到数组
        // 注意：以上几个参数是追加到$data中的，$data中应该同时包含开发文档中要求必填的剔除sign以外的所有数据
        $sign = $this->getSign($data);      //获取签名
        //替换成xml数据
        $data = sprintf($sTpl, $data['appid'], $data['body'], $data['mch_id'], $nonce_str, $notify_url,$data['openid'], $data['out_trade_no'], $data['spbill_create_ip'], $data['total_fee'], $data['trade_type'], $sign);
        return $data;
    }

    /**
     * 解析xml文档，转化为对象
     * @param  String $xmlStr xml文档
     * @return Object         返回Obj对象
     */
    private function xmlToObject($xmlStr) {
        if (!is_string($xmlStr) || empty($xmlStr)) {
            return false;
        }
        // 由于解析xml的时候，即使被解析的变量为空，依然不会报错，会返回一个空的对象，所以，我们这里做了处理，当被解析的变量不是字符串，或者该变量为空，直接返回false
        $postObj = simplexml_load_string($xmlStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $postObj = json_decode(json_encode($postObj));
        //将xml数据转换成对象返回
        return $postObj;
    }


    /**
     * 未付款
     * @return
     */
    public function NotPay()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $data = Db::name('order')->alias('o')->join('line l','l.id = o.ware_id','left')
            ->field('o.*,l.cover,l.title')
            ->where(['o.user_id'=>$user_id,'o.order_status'=>1])->select();
        return json_code(200,'success',$data);
    }

    /**
     * 已付款（未使用 ）
     * @return
     */
    public function AlreadyPay()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $data = Db::name('order')->alias('o')->join('line l','l.id = o.ware_id','left')
            ->field('o.*,l.cover,l.title')
            ->where(['o.user_id'=>$user_id,'o.order_status'=>2])->select();
        return json_code(200,'success',$data);
    }

    /**
     * 已使用
     * @return
     */
    public function AlreadyUse()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $data = Db::name('order')->alias('o')->join('line l','l.id = o.ware_id','left')
            ->field('o.*,l.cover,l.title')
            ->where(['o.user_id'=>$user_id,'o.order_status'=>3])->select();
        return json_code(200,'success',$data);
    }

    /**
     *  我的订单
     */
    public function MyOrder()
    {
        $user_id = OnlineUtils::getUserIdBySid();
        $order_status = input('post.order_status');
        $pageindex = input('post.pageindex');
        $pagesize = input('post.pagesize');
        if( $pageindex <= 0 ){
            $length = 0;
        }else{
            $length = $pagesize*$pageindex;
        }
        if( $order_status == 0){
            $data = Db::name('order')->alias('o')->join('line l','l.id = o.ware_id','left')
                ->field('o.*,l.cover,l.title')
                ->where(['o.user_id'=>$user_id])->limit($length,$pagesize)->select();
        }else{
            $data = Db::name('order')->alias('o')->join('line l','l.id = o.ware_id','left')
            ->field('o.*,l.cover,l.title')
            ->where(['o.user_id'=>$user_id,'o.order_status'=>$order_status])->limit($length,$pagesize)->select();
        }
        return json_code(200,'success',$data);
    }

}